/**
 * Copyright (c) 2020-2030 LiuBoTao [1211265557@qq.com]
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.amos.server.modules.upms.controller;

import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.annotation.SaCheckSafe;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.collection.CollUtil;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.amos.core.basic.annotation.Log;
import org.amos.core.basic.annotation.ParamCheck;
import org.amos.core.basic.base.BaseController;
import org.amos.core.basic.utils.AmosUtils;
import org.amos.core.basic.vo.R;
import org.amos.server.modules.upms.dto.MenuDTO;
import org.amos.server.modules.upms.dto.MenuDragDTO;
import org.amos.server.modules.upms.dto.MenuListDTO;
import org.amos.server.modules.upms.entity.Menu;
import org.amos.server.modules.upms.service.IMenuService;
import org.amos.server.modules.upms.vo.MenuVO;
import org.amos.server.modules.upms.vo.PermissionVO;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 系统菜单 前端控制器
 *
 * @author liubt
 * @since 2020-12-20
 */
@RestController
@RequestMapping("/system/menu")
@RequiredArgsConstructor
public class MenuController extends BaseController {

    private final IMenuService menuService;

    @GetMapping("/routes")
    @ApiOperation(value = "前端菜单数据")
    @Log(value = "前端菜单数据", logResultInfo = false)
    public R routes() {
        List<String> roleList = StpUtil.getRoleList();
        Set<Long> roleIds = new HashSet<>();
        if (CollUtil.isNotEmpty(roleList)) {
            roleIds = roleList.stream().map(Long::valueOf).collect(Collectors.toSet());
        }
        List<MenuVO> menuVOS = menuService.routes(roleIds);
        return R.ok(menuVOS);
    }

    @GetMapping("/permission/info")
    @ApiOperation(value = "用户权限")
    @Log(value = "用户权限")
    public R permissions(@RequestParam Long id) {
        PermissionVO vo = new PermissionVO();
        List<MenuVO> list = menuService.selectTree();
        List<Long> ids = menuService.selectRoleTreeID(id);
        vo.setPermissions(ids);
        vo.setList(list);
        return R.ok(vo);
    }

    @GetMapping("/tenant-package/info")
    @ApiOperation(value = "租户套餐权限")
    @Log(value = "租户套餐权限")
    public R tenantPackageInfo(Long id) {
        PermissionVO vo = new PermissionVO();
        List<MenuVO> list = menuService.selectTree(new MenuListDTO());
        List<Long> ids = Collections.EMPTY_LIST;
        if (Objects.nonNull(id)) {
            ids = menuService.selectPackageTreeID(id);
        }
        vo.setPermissions(ids);
        vo.setList(list);
        return R.ok(vo);
    }

    @PostMapping("/update/drag")
    @ApiOperation(value = "拖拽更新菜单数据")
    @SaCheckPermission("menu:update")
    @SaCheckSafe
    @Log(value = "拖拽更新菜单数据", logResultInfo = false)
    public R updateDrag(@RequestBody @Validated MenuDragDTO dto) {
        List<MenuDTO> dtoList = new ArrayList<>();
        List<Long> ids = dto.getIds();
        Long parentId = dto.getParentId();
        ids.forEach(x -> {
            MenuDTO menuDTO = new MenuDTO();
            menuDTO.setId(x);
            menuDTO.setParentId(Objects.isNull(parentId) ? null : parentId);
            menuDTO.setSort(ids.indexOf(x) + 1);
            dtoList.add(menuDTO);
        });
        List<Menu> menuList = AmosUtils.listCopy(dtoList, Menu.class);
        menuService.updateBatchById(menuList);
        return R.ok();
    }

    @PostMapping("/update")
    @ApiOperation(value = "更新菜单数据")
    @SaCheckPermission("menu:update")
    @SaCheckSafe
    @Log(value = "更新菜单数据", logResultInfo = false)
    public R update(@RequestBody @Validated MenuDTO dto) {
        Menu menu = AmosUtils.copy(dto, Menu.class);
        if (Objects.nonNull(dto.getMeta())) {
            MenuDTO.MetaDTO meta = dto.getMeta();
            menu.setTitle(meta.getTitle());
            menu.setType(meta.getType());
            menu.setIcon(meta.getIcon());
            menu.setHidden(meta.getHidden());
            menu.setHiddenBreadcrumb(meta.getHiddenBreadcrumb());
        }
        Long id = menuService.saveOrUpdateMenu(menu);
        return R.ok(id);
    }

    @PostMapping("/remove")
    @ApiOperation(value = "删除菜单数据")
    @ParamCheck(message = "缺少必要参数")
    @SaCheckPermission("menu:update")
    @SaCheckSafe
    @Log(value = "删除菜单数据", logResultInfo = false)
    public R remove(@RequestBody Set<Long> ids) {
        menuService.remove(ids);
        return R.ok();
    }
}
